import SPI;
import Util;

extends SPI;

init() {
  super();
}

async function modifyConfiguration(context: SPI.InterceptorContext, attributeMap: SPI.AttributeMap): void {
}

async function modifyRequest(context: SPI.InterceptorContext, attributeMap: SPI.AttributeMap): void {
  var request = context.request;
  var config = context.configuration;
  request.headers = {
    host = config.endpoint,
    user-agent = request.userAgent,
    accept = 'application/json',
    ...request.headers
  };

  if (!Util.isUnset(request.body)) {
    var jsonObj = Util.toJSONString(request.body);
    request.stream = jsonObj;
    request.headers.content-type = 'application/json; charset=utf-8';
  }
}

async function modifyResponse(context: SPI.InterceptorContext, attributeMap: SPI.AttributeMap): void {
  var request = context.request;
  var response = context.response;
  if (Util.is4xx(response.statusCode) || Util.is5xx(response.statusCode)) {
    var _res = Util.readAsJSON(response.body);
    var err = Util.assertAsMap(_res);
    err.statusCode = response.statusCode;
    throw {
      code = `${defaultAny(err.Code, err.code)}`,
      message = `code: ${response.statusCode}, ${defaultAny(err.Message, err.message)} request id: ${defaultAny(err.RequestId, err.requestid)}`,
      data = err,
      description = `${defaultAny(err.Description, err.description)}`,
      accessDeniedDetail = defaultAny(err.AccessDeniedDetail, err.accessdenieddetail),
    };
  }
  if (Util.equalNumber(response.statusCode, 204)) {
      Util.readAsString(response.body);
  } else if (Util.equalString(request.bodyType, 'binary')) {
    response.deserializedBody = response.body;
  } else if (Util.equalString(request.bodyType, 'byte')) {
    var byt = Util.readAsBytes(response.body);
    response.deserializedBody = byt;
  } else if (Util.equalString(request.bodyType, 'string')) {
    var str = Util.readAsString(response.body);
    response.deserializedBody = str;
  } else if (Util.equalString(request.bodyType, 'json')) {
    var obj = Util.readAsJSON(response.body);
    var res = Util.assertAsMap(obj);
    response.deserializedBody = res;
  } else if (Util.equalString(request.bodyType, 'array')) {
    var arr = Util.readAsJSON(response.body);
    response.deserializedBody = arr;
  } else {
    response.deserializedBody = Util.readAsString(response.body);
  }
}

function defaultAny(inputValue: any, defaultValue: any): any {
  if (Util.isUnset(inputValue)) {
    return defaultValue;
  }
  return inputValue;
}